package com.sa.app.activities;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;

import com.sa.app.R;
import com.sa.app.fragments.HomeFragment;
import com.sa.app.fragments.ItemsFragment;
import com.sa.app.fragments.MapFragment;
import com.sa.app.fragments.StatsFragment;
import com.sa.app.objects.Item;
import com.sa.app.objects.Region;
import com.sa.app.utilities.ComparatorItem;
import com.sa.app.utilities.DataBaseManager;
import com.sa.app.utilities.MyApplication;

public class MainActivity extends FragmentActivity implements
		ActionBar.TabListener {

	/** Called when the activity is first created. */

	private DataBaseManager dataBaseManager;

	private List<Item> items;

	private List<Region> regions = new ArrayList<Region>();

	private List<String> download = new ArrayList<String>();

	private String goToMeFromDataBase;

	private Integer ordination = MyApplication.ALIAS;

	private SectionsPagerAdapter mSectionsPagerAdapter;
	private ViewPager mViewPager;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		initializeTabs();

		MyApplication ma = (MyApplication) getApplicationContext();
		dataBaseManager = ma.getDataBase();

		goToMeFromDataBase = "";

		Intent intent = getIntent();
		if (intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
			String[] tagData = readingNFCTag(intent);
			String tagID = tagData[0];

			// Si tagID no existe en la BD
			if (!dataBaseManager.isItemInDataBase(tagID)) {

				String[] message = tagData[1].split(";");
				download.add(tagID);
				download.add(message[0]);
				download.add(message[1]);
				download.add(message[2]);

				items = dataBaseManager.generateItemsList();

				// Si ya existe
			} else {
				// Recuperar de la BD
				goToMeFromDataBase = tagID;
			}

			//

		} else if (intent.getAction().equals(Intent.ACTION_MAIN)) {

		} else if (intent.getAction().equals("ItemActivity")) {

		} else {

			throw new InvalidParameterException(
					"The intent doesn't have a valid action for this activity");
		}
		// LEER
		// Batería de prueba con ejemplos, las imagenes de los Items deben ser
		// metidas en /data/data/com.sa.app/files desde un terminal con permisos
		// de superusuario. Si se borra el marco digital se agregan de nuevo
		// todos los Items de la batería. En Tv salón se ven ejemplos de
		// servicios virtuales y reales en las listas. Para ver ejemplos de
		// DatasheetFragment es necesario taguear un Item

		List<List<String>> it = dataBaseManager
				.query("SELECT * FROM items WHERE NFCID='nfcid_marcodigital'");

		if (dataBaseManager.isOpen() && it.isEmpty()) {

			dataBaseManager.insertRegion("Casa", 37394437, -5984465, 180);

			dataBaseManager.insertRegion("Club", 37389811, -6005381, 180);
			dataBaseManager.insertRegion("Trabajo", 37397164, -5995274, 180);
			dataBaseManager.insertRegion("Facultad", 37390252, -5998365, 180);

			// Casa
			dataBaseManager.insertItem("nfcid_tv", "TV Salón", "urlXml1", 1,
					"Sony Bravia", "S/B3", "urlImage1", 37394437, -5984465);
			dataBaseManager.insertItem("nfcid_despertador",
					"Despertador dormitorio", "urlXml2", 2, "Good Dream",
					"M-500", "urlImage2", 37394437, -5984465);
			dataBaseManager.insertItem("nfcid_impresora", "Impresora estudio",
					"urlXml3", 3, "HP Deskjet", "W6640", "urlImage3", 37394437,
					-5984465);
			dataBaseManager.insertItem("nfcid_alarma", "Alarma antirobos",
					"urlXml3", 3, "Securitas Direct", "Sec12", "urlImage3",
					37394437, -5984465);
			dataBaseManager.insertItem("nfcid_microondas", "Microondas",
					"urlXml3", 3, "Daewood", "Z6", "urlImage3", 37394437,
					-5984465);

			// Trabajo
			dataBaseManager.insertItem("nfcid_marcodigital", "Marco digital",
					"urlXml1", 1, "Samsung", "Look3000", "urlImage1", 37397164,
					-5995274);
			dataBaseManager.insertItem("nfcid_aireacondicionado", "Aire",
					"urlXml2", 2, "Fujitsu", "X-Cool 3B", "urlImage2",
					37397164, -5995274);

			dataBaseManager
					.insertItem("nfcid_consola", "Consola", "urlXml3", 3,
							"Microsoft", "Xbox 720", "urlImage3", 37397164,
							-5995274);

			dataBaseManager
					.insertVirtualService(
							"Programacion de hoy",
							"nfcid_tv",
							"Consulta la programacion de hoy con todo detalle y elige lo que quieres ver",
							"serviceURL1");
			dataBaseManager
					.insertVirtualService(
							"Programacion semanal",
							"nfcid_tv",
							"Consulta la planificacion de la semana y planificate para que no te pierdas nada",
							"serviceURL2");
			dataBaseManager.insertVirtualService("El tiempo", "nfcid_tv",
					"Consulta el clima en tu ciudad", "serviceURL2");
			dataBaseManager
					.insertVirtualService(
							"Programas favoritos",
							"nfcid_tv",
							"Apunta aqui tus series y peliculas favoritas para que no te las pierdas",
							"serviceURL1");
			dataBaseManager.insertVirtualService("Noticias", "nfcid_tv",
					"Informese de todo lo que está ocurriendo", "serviceURL2");
			dataBaseManager
					.insertVirtualService(
							"Debate",
							"nfcid_tv",
							"Comparta opiniones sobre sus series y peliculas favoritas",
							"serviceURL2");
			dataBaseManager
					.insertVirtualService(
							"Información adicional",
							"nfcid_tv",
							"Aqui puedes consultar informacion adicional sobre el fabricante y futuros modelos",
							"serviceURL2");

			dataBaseManager.insertRealService("Mando a distancia", "nfcid_tv",
					"Controla tu Smarth-TV con tu Smarth-Phone", "serviceURL1");
			dataBaseManager
					.insertRealService(
							"Grabación",
							"nfcid_tv",
							"Programa la hora de tu emision favorita para poder verla cuantas veces quieras y cuando quieras",
							"serviceURL2");
			dataBaseManager.insertRealService("Navegador web", "nfcid_tv",
					"Visita infinidad de paginas con tu magnifico Smarth-TV",
					"serviceURL2");
			dataBaseManager
					.insertRealService(
							"Transferir video o foto",
							"nfcid_tv",
							"Envia tus videos y fotos a tu Smart-TV para poder visualizarlos en su magnifica pantalla",
							"serviceURL1");
			dataBaseManager.insertRealService("Videoclub", "nfcid_tv",
					"Compra y alquila tantas peliculas como te apetezca",
					"serviceURL2");
			dataBaseManager.insertRealService("Instalación", "nfcid_tv",
					"Gestiona tus canales desde aqui con una comoda interfaz",
					"serviceURL2");
			dataBaseManager
					.insertRealService(
							"Descargar plugins",
							"nfcid_tv",
							"Descarga infinidad de plugins para tu SmartTV desde nuestra tienda",
							"serviceURL2");

			Date date = new Date(2012, 7, 18, 10, 30, 12);

			date = new Date(2012 - 1900, 7, 10, 15, 32, 22);
			dataBaseManager.insertUse("nfcid_tv", 37397164, -5995274, date,
					MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 16, 32, 22);
			dataBaseManager.insertUse("nfcid_despertador", 37394437, -5984465,
					date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 17, 32, 22);
			dataBaseManager.insertUse("nfcid_impresora", 37397164, -5995274,
					date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 18, 32, 22);
			dataBaseManager.insertUse("nfcid_alarma", 37394437, -5984465, date,
					MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 19, 32, 22);
			dataBaseManager.insertUse("nfcid_microondas", 37397164, -5995274,
					date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 20, 32, 22);
			dataBaseManager.insertUse("nfcid_marcodigital", 37394437, -5984465,
					date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 21, 32, 22);
			dataBaseManager.insertUse("nfcid_aireacondicionado", 37397164,
					-5995274, date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 22, 32, 22);
			dataBaseManager.insertUse("nfcid_consola", 37394437, -5984465,
					date, MyApplication.TAGGED);

			date = new Date(2012 - 1900, 7, 10, 23, 32, 22);
			dataBaseManager.insertUse("nfcid_consola", null, null, date,
					MyApplication.MAIN);

			date = new Date(61303426212000L);

		}

		SharedPreferences settings = getPreferences(MODE_PRIVATE);
		ordination = settings.getInt("ordination", MyApplication.ALIAS);

	}

	public void onStop() {
		super.onStop();
		SharedPreferences settings = getPreferences(MODE_PRIVATE);
		SharedPreferences.Editor editor = settings.edit();
		editor.putInt("ordination", ordination);
		editor.commit();

	}

	public List<Region> getRegions() {
		return regions;
	}

	@Override
	/** Needed to keep config between orientation changes ***/
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}

	public List<String> getInformationToDownload() {
		return download;
	}

	public DataBaseManager getDataBaseManager() {
		return dataBaseManager;
	}

	public List<Item> getItemsListFromRegion(Region r) {
		items = dataBaseManager.generateItemsListFromRegion(r);
		sortBy(ordination, items);
		return items;
	}

	private List<Item> sortBy(Integer ordination2, List<Item> items2) {
		Collections.sort(items2, new ComparatorItem(ordination2,
				dataBaseManager));
		return items2;
	}

	public List<Region> getRegionsList() {
		regions = dataBaseManager.generateRegionsList();
		return regions;
	}

	public String getGoToMeFromDataBase() {
		return goToMeFromDataBase;
	}

	public void setGoToMeFromDataBase(String n) {
		goToMeFromDataBase = n;
	}

	private void initializeTabs() {
		// Create the adapter that will return a fragment for each of the three
		// primary sections
		// of the app.

		mSectionsPagerAdapter = new SectionsPagerAdapter(
				getSupportFragmentManager());

		// Set up the action bar.
		final ActionBar actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

		// Set up the ViewPager with the sections adapter.
		mViewPager = (ViewPager) findViewById(R.id.pager);
		mViewPager.setAdapter(mSectionsPagerAdapter);

		// When swiping between different sections, select the corresponding
		// tab.
		// We can also use ActionBar.Tab#select() to do this if we have a
		// reference to the
		// Tab.
		mViewPager
				.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
					@Override
					public void onPageSelected(int position) {
						actionBar.setSelectedNavigationItem(position);
					}
				});

		// For each of the sections in the app, add a tab to the action bar.
		for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
			// Create a tab with text corresponding to the page title defined by
			// the adapter.
			// Also specify this Activity object, which implements the
			// TabListener interface, as the
			// listener for when this tab is selected.

			actionBar.addTab(actionBar.newTab()
					.setText(mSectionsPagerAdapter.getPageTitle(i))
					.setTabListener(this));
		}
	}

	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.sortby) {
			final CharSequence[] items = { getString(R.string.sort_alias),
					getString(R.string.sort_manufacturer),
					getString(R.string.sort_most_used) };

			// TODO: Pasar a @string
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Sort by");
			builder.setItems(items, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int item) {
					// Do something with the selection

					if (item == MyApplication.ALIAS) {
						// alias
						ordination = MyApplication.ALIAS;

					} else if (item == MyApplication.MANUFACTURER) {
						// manufacturer
						ordination = MyApplication.MANUFACTURER;

					} else if (item == MyApplication.MOST_USED) {
						// most used

						ordination = MyApplication.MOST_USED;

					}

					mSectionsPagerAdapter.getItemsFragment().onResume();

				}
			});
			AlertDialog alert = builder.create();
			alert.show();

		}
		return false;
	}

	@Override
	public void onResume() {
		super.onResume();
		try{
		mSectionsPagerAdapter.getItemsFragment().initializeSpinner();
		}catch(Exception e){
			
		}
	}

	@Override
	public void onPause() {
		super.onPause();

	}

	public String[] readingNFCTag(Intent intent) {
		String res[] = new String[2];
		Parcelable[] rawMsgs = intent
				.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
		Tag t = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
		if (rawMsgs != null) {
			NdefMessage msg = (NdefMessage) rawMsgs[0];
			// record 0 contains the MIME type, record 1 is the AAR, if present
			String message = new String(msg.getRecords()[0].getPayload());
			// record 0 contains the MIME type, record 1 is the AAR, if present

			// TODO por que no puedo hacer new String(byte[]);
			byte[] id = t.getId();
			String idS = "";
			for (int i = 0; i < id.length; i++) {
				idS = idS + id[i];
			}

			res[0] = idS;
			res[1] = message;

		} else {

			// TODO Mirar que tipo de excepcion es la adecuada
			throw new InvalidParameterException(
					"Error while reading Ndef_Messages");
		}
		return res;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return true;
	}

	public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
		// TODO Auto-generated method stub

	}

	public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
		// TODO Auto-generated method stub
		// When the given tab is selected, switch to the corresponding page in
		// the ViewPager.
		mViewPager.setCurrentItem(tab.getPosition());

	}

	public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
		// TODO Auto-generated method stub

	}

	/**
	 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
	 * one of the primary sections of the app.
	 */
	public SectionsPagerAdapter getSectionsPagerAdapter() {
		return mSectionsPagerAdapter;
	}

	public class SectionsPagerAdapter extends FragmentPagerAdapter {

		private ItemsFragment itemsFragment = new ItemsFragment();
		private MapFragment mapFragment = new MapFragment();

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);

		}

		@Override
		public Fragment getItem(int i) {
			Fragment fragment = null;
			if (i == 0) {
				fragment = new HomeFragment();
			} else if (i == 1) {
				fragment = itemsFragment;
			} else if (i == 2) {
				fragment = mapFragment;
			} else if (i == 3) {
				fragment = new StatsFragment();
			}
			// Log.i("id","id "+fragment.getId());

			return fragment;
		}

		@Override
		public int getCount() {
			return 4;
		}

		@Override
		public CharSequence getPageTitle(int position) {
			switch (position) {
			case 0:
				return getString(R.string.home).toUpperCase();
			case 1:
				return getString(R.string.items).toUpperCase();
			case 2:
				return getString(R.string.map).toUpperCase();
			case 3:
				return getString(R.string.stats).toUpperCase();

			}
			return null;
		}

		public ItemsFragment getItemsFragment() {
			return itemsFragment;
		}

		public MapFragment getMapFragment() {
			return mapFragment;
		}
	}

}